Conversation
Updates vendored plette from 2.1.0 to 2.2.1, which adds the `cool-down-period` field to the `[pipenv]` section model with validation and a `cool_down_period_timedelta` helper property. Signed-off-by: Oz Tiram <[email protected]>
Reads the new `cool-down-period = "<n>d"` Pipfile setting introduced in plette 2.2.1 and forwards it to pip's `--uploaded-prior-to P<n>D` flag during dependency resolution, restricting the resolver to package versions uploaded at least N days ago. Includes unit tests for the arg-conversion helper and the injection into `extra_pip_args`, an integration test verifying the lock succeeds with the setting present, and documentation in docs/pipfile.md. Signed-off-by: Oz Tiram <[email protected]>
Replace nested and sequential if-blocks with short-circuit or-expressions, reducing branch count without any behavioural change. Signed-off-by: Oz Tiram <[email protected]>
b046314 to
2ccdaef
Compare
…f injecting into pip args Passing --uploaded-prior-to via PIPENV_EXTRA_PIP_ARGS caused the subprocess resolver to reject it as an unknown option. Instead, set pip_options.uploaded_prior_to directly in Resolver.pip_options as a datetime object — the same pattern used for other pip options like pre and cache_dir. Rename _get_uploaded_prior_to_arg → _get_cool_down_timedelta to reflect that it now returns a timedelta (or None) rather than a pip arg list. Update unit tests accordingly. Switch the integration test from the private pypi fixture to pipenv_instance_pypi (real PyPI), since pypiserver does not expose upload-time metadata and pip errors out rather than silently ignoring the filter when --uploaded-prior-to is supplied. Signed-off-by: Oz Tiram <[email protected]>
There was a problem hiding this comment.
Pull request overview
Adds support for a Pipfile [pipenv] setting cool-down-period to restrict resolution to package versions uploaded at least N days ago (via pip’s --uploaded-prior-to behavior), along with a vendored plette bump, docs, news, and tests.
Changes:
- Set pip’s
uploaded_prior_tooption inResolver.pip_optionsbased on[pipenv] cool-down-period. - Bump vendored
pletteto2.2.1and add corresponding vendored model changes. - Add documentation, news entries, and unit/integration tests for the new setting.
Reviewed changes
Copilot reviewed 6 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
pipenv/utils/resolver.py |
Implements cool-down-period parsing and wires it into pip options as uploaded_prior_to. |
tests/unit/test_resolver_regressions.py |
Adds unit tests for parsing and intended pip_options behavior. |
tests/integration/test_lock.py |
Adds integration coverage to ensure cool-down-period affects locking. |
docs/pipfile.md |
Documents the new Pipfile setting and its behavior/limitations. |
pipenv/vendor/vendor.txt |
Bumps vendored plette version pin. |
pipenv/vendor/plette/__init__.py |
Updates vendored plette version constant. |
pipenv/vendor/plette/models/sections.py |
Adds cool-down-period validation/helpers to vendored plette models. |
pipenv/vendor/plette/lockfiles.py |
Updates vendored lockfile encoding implementation. |
pipenv/vendor/plette/__main__.py |
Adds a vendored CLI entry point for validating Pipfiles/Lockfiles. |
news/+cool-down-period.feature.rst |
Announces the new feature. |
news/+bump-plette.vendor.rst |
Notes the vendored dependency bump. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @pytest.mark.lock | ||
| @pytest.mark.requirements | ||
| def test_lock_respects_cool_down_period(pipenv_instance_pypi): | ||
| """cool-down-period in [pipenv] passes --uploaded-prior-to to the resolver. | ||
|
|
||
| Uses the real PyPI because it exposes upload-time metadata, which pip | ||
| requires when --uploaded-prior-to is supplied. The 30-day window is wide | ||
| enough to always include a stable release of `six`. | ||
| """ | ||
| with pipenv_instance_pypi() as p: | ||
| with open(p.pipfile_path, "w") as f: | ||
| f.write( | ||
| f""" | ||
| [[source]] | ||
| url = "{p.index_url}" | ||
| verify_ssl = true | ||
| name = "pypi" | ||
|
|
||
| [packages] | ||
| six = "*" | ||
|
|
||
| [pipenv] | ||
| cool-down-period = "30d" | ||
| """ | ||
| ) | ||
| c = p.pipenv("lock") | ||
| assert c.returncode == 0, c.stderr | ||
| assert "six" in p.lockfile["default"] |
There was a problem hiding this comment.
This integration test uses the real PyPI (network dependency) but isn’t marked with @pytest.mark.needs_internet like other tests in this file (e.g. test_private_index_skip_lock). Without the marker, the test is likely to fail in offline/isolated CI runs. Add the appropriate internet/network marker(s) consistent with the rest of the integration suite.
| The value must be a string in `<int>d` format (e.g. `"30d"` for 30 days). Internally | ||
| pipenv translates this to pip's `--uploaded-prior-to P30D` flag, which is only | ||
| effective against indexes that expose upload-time metadata as described in the |
There was a problem hiding this comment.
The docs say pipenv translates cool-down-period to pip’s --uploaded-prior-to P30D flag, but the implementation sets pip_options.uploaded_prior_to directly to a cutoff datetime (now(UTC) - timedelta). Update the wording to reflect the actual behavior (cutoff datetime) and/or note that pip supports both ISO datetimes and P<n>D durations.
| The value must be a string in `<int>d` format (e.g. `"30d"` for 30 days). Internally | |
| pipenv translates this to pip's `--uploaded-prior-to P30D` flag, which is only | |
| effective against indexes that expose upload-time metadata as described in the | |
| The value must be a string in `<int>d` format (e.g. `"30d"` for 30 days). Internally, | |
| pipenv computes a cutoff datetime in UTC (`now - N days`) and passes that cutoff to | |
| pip's uploaded-prior-to filtering. Pip also supports duration-style values such as | |
| `P30D`, but pipenv's behavior here is based on a concrete cutoff timestamp. This is | |
| only effective against indexes that expose upload-time metadata as described in the |
| @pytest.mark.utils | ||
| def test_pip_options_sets_uploaded_prior_to_from_cool_down_period(): | ||
| """Resolver.pip_options sets uploaded_prior_to when cool-down-period is configured.""" | ||
| import datetime | ||
| from types import SimpleNamespace | ||
|
|
||
| project = _make_project("30d") | ||
| project.s.PIPENV_CACHE_DIR = "/tmp/cache" | ||
| project.packages = {} | ||
|
|
||
| resolver = Resolver.__new__(Resolver) | ||
| resolver.project = project | ||
| resolver.sources = [] | ||
|
|
||
| before = datetime.datetime.now(datetime.timezone.utc) | ||
| cool_down = _get_cool_down_timedelta(project) | ||
| assert cool_down is not None | ||
| cutoff = datetime.datetime.now(datetime.timezone.utc) - cool_down | ||
| after = datetime.datetime.now(datetime.timezone.utc) - cool_down | ||
|
|
||
| # cutoff should be approximately 30 days ago | ||
| assert before - datetime.timedelta(days=30, seconds=1) < cutoff < after + datetime.timedelta(seconds=1) |
There was a problem hiding this comment.
This test doesn’t exercise Resolver.pip_options at all: it computes cutoff = now - cool_down locally and asserts on that, so it will pass even if pip_options.uploaded_prior_to is never set. Update the test to call resolver.pip_options (mocking resolver.pip_command.parser.parse_args as needed) and assert that pip_options.uploaded_prior_to is set to approximately now - timedelta(days=30) when cool-down-period is configured. Also SimpleNamespace is imported but unused.
Add "cool-down-period" pipenv
See this feature added to pip:
pypa/pip#13674
The fix
Bumped plette which added a syntax support for this in Pipfile.
Added mathing parsing in pipenv, tests and documentation.
News file added.